package editor3d;
import java.util.*;
/**
* Clase que guarda informacion de cada uno de los simbolos
*/
public class Simbolo implements Cloneable {
	protected String nombre = null;
	protected int rol = -1;
	protected int tamanio = -1;
	protected int tipo = -1;
	protected int puntero = -1;
	protected int clasi = -1;
	protected int nivel = -1;
	protected int acceso = -1;
	protected boolean estatico = false;
	protected String nombreTipoClase = null;
	protected String nombreMeth = null;
	protected String nombreObj = null;
	protected LinkedList <Integer> extra = new LinkedList <Integer> ();
	protected boolean cons = false;

	public void setEstatico(boolean estatico){
		this.estatico = estatico;
	}
	public boolean getEstatico(){
		return estatico;
	}

	public void setAcceso(int acceso){
		this.acceso = acceso;
	}
	public int getAcceso(){
		return acceso;
	}

	public boolean isCons(){
		return cons;
	}

	public void setCons(boolean cons){
		this.cons = cons;
	}

	/**
	* Si es una matriz regresa el numero de dimensiones de la matriz
	* @return el numero de dimensiones de la matriz
	*/
	public int getDimension(){
		return extra.size();
	}

	/**
	* Retorna la linkedList de la dimensiones de una matriz
	*/
	public LinkedList <Integer> getDimensiones(){
		return extra;
	}

	/**
	* Para el calculo de la posicion de la matriz regresa el numero desde una posicion
	* @param pos Numero de la posicion de la matriz
	* @return El tamaño que debe recorrer para la posicion
	*/
	public int getDimAt(int pos){
		int acum = 1;
		for(int i = pos; i < extra.size(); i++)
			acum *= extra.get(i);
		return acum;
	}

	/**
	* Coloca un dato en la lista de tamanio de matrices
	* @param dato El tamanio de una matriz en una posicion
	*/
	public void addData(int dato){
		extra.add(dato);
	}

	public String getNombre(){
		return nombre;
	}
	public void setNombre(String nombre){
		this.nombre = nombre;
	}

	public String getNombreMeth(){
		return nombreMeth;
	}
	public void setNombreMeth(String nombreMeth){
		this.nombreMeth = nombreMeth;
	}

	public String getNombreObj(){
		return nombreObj;
	}
	public void setNombreObj(String nombreObj){
		this.nombreObj = nombreObj;
	}

	public void setRol(int rol){
		this.rol = rol;
	}
	public int getRol(){
		return rol;
	}

	public void setTipo(int tipo){
		this.tipo = tipo;
		setClasi(CLAS_SIM);
		if(tipo == TIPO_INT)
			tamanio = SIZE_INT;
		else if(tipo == TIPO_FLOAT)
			tamanio = SIZE_FLOAT;
		else if(tipo == TIPO_CHAR)
			tamanio = SIZE_CHAR;
		else if(tipo == TIPO_DOUBLE)
			tamanio = SIZE_DOUBLE;
		else if(tipo == TIPO_LONG)
			tamanio = SIZE_LONG;
		else if(tipo == TIPO_STR)
			tamanio = SIZE_STR;
		else if(tipo == TIPO_BOOL)
			tamanio = SIZE_BOOL;
		else if(tipo == TIPO_OBJ)
			setClasi(CLAS_OBJ);
	}

	public void setNombreTipoClase(String nombreTipoClase){
		this.nombreTipoClase = nombreTipoClase;
	}

	public String getNombreTipoClase(){
		return nombreTipoClase;
	}

	public int getTipo(){
		return tipo;
	}

	public void setClasi(int clasi){
		this.clasi = clasi;
	}
	public int getClasi(){
		return clasi;
	}

	public void setPuntero(int puntero){
		this.puntero = puntero;
	}
	public int getPuntero(){
		return puntero;
	}

	public void setTamanio(int tamanio){
		this.tamanio = tamanio;
	}

	public void setNivel(int nivel){
		this.nivel = nivel;
	}

	public int getNivel(){
		return nivel;
	}

	/**
	* Metodo que retorna el tamanio del dato en la tabla de simbolos
	* @return Retorna el tamanio en  bytes
	*/
	public int getTamanio(){
		if(getClasi() == Simbolo.CLAS_MAT){
			int total = 1;
			for(int i = 0; i<extra.size(); i++)
				total *= extra.get(i);
			return total*tamanio;
		}
		return tamanio;
	}
	/**
	* Constante que identifica el acceso que juega el dato en el archivo fuente
	*/
	public static final int ACS_PUB = 0;
	public static final int ACS_PRO = 1;
	public static final int ACS_PRI = 2;

	/**
	* Constante que identifica que rol juega el dato en el archivo fuente
	*/
	public static final int ROL_FUN = 0;
	public static final int ROL_PRO = 1;
	public static final int ROL_LCL = 2;
	public static final int ROL_GBL = 3;

	/**
	* Constante que representa el tipo del dato en la tabla de simbolos
	*/
	public static final int TIPO_INT = 0;
	public static final int TIPO_FLOAT = 1;
	public static final int TIPO_CHAR = 2;
	public static final int TIPO_DOUBLE = 3;
	public static final int TIPO_LONG = 4;
	public static final int TIPO_VOID = 5;
	public static final int TIPO_STR = 6;
	public static final int TIPO_OBJ = 8;
	public static final int TIPO_BOOL = 9;

	/**
	* Constante que representa si es un dato simple, un tipo de matriz o un objeto
	*/
	public static final int CLAS_SIM = 0;
	public static final int CLAS_MAT = 1;
	public static final int CLAS_OBJ = 2;
	public static final int CLAS_ABST = 4;
	/**
	* Constante que representa el tamanio de un tipo de dato
	*/
	public static final int SIZE_INT = 1;
	public static final int SIZE_FLOAT = 1;
	public static final int SIZE_CHAR = 1;
	public static final int SIZE_DOUBLE = 1;
	public static final int SIZE_LONG = 1;
	public static final int SIZE_VOID = 0;
	public static final int SIZE_STR = 30;
	public static final int SIZE_BOOL = 1;
// 	public static final int SIZE_INT = 4;
// 	public static final int SIZE_FLOAT = 4;
// 	public static final int SIZE_CHAR = 1;
// 	public static final int SIZE_DOUBLE = 8;
// 	public static final int SIZE_LONG = 12;
// 	public static final int SIZE_VOID = 0;
// 	public static final int SIZE_STR = 30;

	@Override
	public Simbolo clone(){
		Simbolo obj=null;
		try{
				obj=(Simbolo)super.clone();
		}catch(CloneNotSupportedException ex){
			System.out.println(" no se puede duplicar");
		}
		obj.extra=(LinkedList <Integer>)obj.extra.clone();
		return obj;
	}

	@Override
	public String toString(){
		String temp = "Nombre: "+nombre +";\n\tTipo: "+tipo+"; Rol: "+ rol+"; Puntero: "+puntero+"; Tamanio: "+getTamanio()+"; Clasi: "+clasi+"; Nivel: "+nivel+"; Method: "+nombreMeth+"; Class: "+nombreObj+"; TipoClase: "+nombreTipoClase+"; Acceso: "+acceso+";";
		return temp;
	}
}
